package com.zmn.oms.dubbo.impl.zmn.normal.order;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.zmn.base.engineer.common.dro.foreign.engineer.ForeignEngineerDetailInfoDRO;
import com.zmn.base.engineer.dubbo.interfaces.engineer.cooperate.EngineerCooperateInfoListRemoteService;
import com.zmn.base.engineer.dubbo.interfaces.foreign.EngineerListRemoteService;
import com.zmn.base.oms.common.model.es.orderwork.EsOrderWork;
import com.zmn.base.oms.common.model.es.orderwork.EsOrderWorkProduct;
import com.zmn.biz.abnormal.common.dro.AbnormalCategDRO;
import com.zmn.biz.abnormal.dubbo.interfaces.AbnormalListRemoteService;
import com.zmn.biz.complain.common.dro.complain.ChsComplainSimpleDRO;
import com.zmn.biz.complain.dubbo.interfaces.complain.ChsComplainApiListRemoteService;
import com.zmn.common.dto2.Option;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.amount.AmountUtil;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.consts.GlobalConsts;
import com.zmn.oms.business.interfaces.log.OrderLogBService;
import com.zmn.oms.business.interfaces.servtype.ServItemBService;
import com.zmn.oms.business.interfaces.work.OrderWorkListBService;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.OrderDeatilSpoolConsts;
import com.zmn.oms.common.constant.OrderLogConsts;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.common.dio.normal.order.PageByCheckoutTimeDIO;
import com.zmn.oms.common.dio.normal.order.PageByCompleteTimeDIO;
import com.zmn.oms.common.dro.order.CheckoutedOrder;
import com.zmn.oms.common.dro.order.CompletedOrder;
import com.zmn.oms.common.dro.order.MasterOrderWorkDRO;
import com.zmn.oms.common.dto.MapDTO;
import com.zmn.oms.common.enums.EncryptFieldTypeEnum;
import com.zmn.oms.dubbo.dto.common.work.OrderLogDRO;
import com.zmn.oms.dubbo.dto.zmn.order.*;
import com.zmn.oms.dubbo.dto.zmn.order.sourcechannel.SourceChannelOrderDRO;
import com.zmn.oms.dubbo.dto.zmn.order.sourcechannel.SourceChannelOrderPageDRO;
import com.zmn.oms.dubbo.dto.zmn.order.sourcechannel.SourceChannelOrderQueryDIO;
import com.zmn.oms.dubbo.dto.zmn.serviceitem.DetailProductDRO;
import com.zmn.oms.dubbo.dto.zmn.serviceitem.DetailServiceItemDRO;
import com.zmn.oms.dubbo.interfaces.zmn.normal.order.ZsNormalOrderListRemoteService;
import com.zmn.oms.dubbo.utils.DubboConsts;
import com.zmn.oms.model.entity.changerecord.OrderChangeRecord;
import com.zmn.oms.model.entity.detail.OrderDetail;
import com.zmn.oms.model.entity.log.OrderLog;
import com.zmn.oms.model.entity.master.OrderMaster;
import com.zmn.oms.model.entity.order.OrderExtend;
import com.zmn.oms.model.entity.product.OrderProduct;
import com.zmn.oms.model.entity.product.OrderProductExtend;
import com.zmn.oms.model.entity.serviceitem.OrderServiceItem;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.entity.work.OrderWorkQuery;
import com.zmn.oms.model.entity.work.list.OrderWorkSourceChannelQuery;
import com.zmn.oms.services.interfaces.changerecord.OrderChangeRecordService;
import com.zmn.oms.services.interfaces.detail.OrderDetailService;
import com.zmn.oms.services.interfaces.master.OrderMasterService;
import com.zmn.oms.services.interfaces.order.OrderExtendService;
import com.zmn.oms.services.interfaces.orderencrypt.OrderEncryptService;
import com.zmn.oms.services.interfaces.product.OrderProductExtendService;
import com.zmn.oms.services.interfaces.product.OrderProductService;
import com.zmn.oms.services.interfaces.serviceitem.OrderServiceItemService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.pay.common.constant.PayConsts;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 类描述：普通单查询
 *
 * @author yule
 * @date 2019/04/10 10:05
 */
@Slf4j
@Service(loadbalance = "roundrobin", timeout = 5000, version = DubboConsts.INTERFACE_VERSION, validation = "true")
public class ZsNormalOrderListRemoteServiceImpl implements ZsNormalOrderListRemoteService {

    @Autowired
    OrderWorkListBService orderWorkListBService;
    @Autowired
    OrderWorkService orderWorkService;
    @Autowired
    OrderDetailService orderDetailService;
    @Autowired
    OrderChangeRecordService orderChangeRecordService;
    @Autowired
    OrderProductExtendService orderProductExtendService;
    @Autowired
    OrderServiceItemService orderServiceItemService;
    @Autowired
    OrderMasterService orderMasterService;
    @Autowired
    OrderLogBService orderLogBService;
    @Autowired
    OrderProductService orderProductService;
    @Autowired
    OrderEncryptService orderEncryptService;
    @Autowired
    ServItemBService servItemBService;
    @Autowired
    OrderExtendService orderExtendService;
    @Reference(version = com.zmn.base.engineer.common.constants.DubboConsts.INTERFACE_VERSION, check = false)
    EngineerListRemoteService engineerListRemoteService;
    @Reference(version = com.zmn.biz.complain.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    ChsComplainApiListRemoteService chsComplainApiListRemoteService;
    @Reference(version = com.zmn.biz.abnormal.common.constant.DubboConsts.INTERFACE_VERSION , check = false, timeout = 2000)
    AbnormalListRemoteService abnormalListRemoteService;
    //@Reference(version = com.zmn.base.engineer.common.constants.DubboConsts.INTERFACE_VERSION, check = false)
    //private EngineerProductGroupListRemoteService engineerProductGroupListRemoteService;

    @Reference(version = com.zmn.base.engineer.common.constants.DubboConsts.INTERFACE_VERSION, check = false)
    private EngineerCooperateInfoListRemoteService engineerCooperateInfoListRemoteService;

    @Override
    public ResponseDTO<OrderWorkDRO> getOrderWorkByKey(@NotNull Long workId, @NotNull Long orderId) {
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
        if (Objects.isNull(orderWork)) {
            return ResponseDTO.fail("订单不存在");
        }

        OrderWorkDRO orderWorkDRO = BeanMapper.map(orderWork, OrderWorkDRO.class);

        // 地址信息
        OrderDetail orderDetail = orderDetailService.findOrderDetailByKey(orderId);
        orderWorkDRO.setServCategName(orderDetail.getServCategName());
        orderWorkDRO.setProductInfo(orderDetail.getProductInfo());
        orderWorkDRO.setProvinceId(orderDetail.getProvinceId());
        orderWorkDRO.setProvinceName(orderDetail.getProvinceName());
        orderWorkDRO.setCityName(orderDetail.getCityName());
        orderWorkDRO.setCountyId(orderDetail.getCountyId());
        orderWorkDRO.setCountyName(orderDetail.getCountyName());
        orderWorkDRO.setLongitude(orderDetail.getLongitude());
        orderWorkDRO.setLatitude(orderDetail.getLatitude());
        orderWorkDRO.setAddress(orderDetail.getAddress());
        orderWorkDRO.setStreet(orderDetail.getStreet());
        orderWorkDRO.setStreetId(orderDetail.getStreetId());
        orderWorkDRO.setUserName(orderDetail.getUserName());

        // 行政公司
        orderWorkDRO.setGridCompanyId(orderDetail.getGridCompanyId());
        orderWorkDRO.setGridCompanyName(orderDetail.getGridCompanyName());
        orderWorkDRO.setGridManageCompanyId(orderDetail.getGridManageCompanyId());
        orderWorkDRO.setGridManageCompanyName(orderDetail.getGridManageCompanyName());

        OrderChangeRecord orderChangeRecord = orderChangeRecordService.getChangeRecordByOrderId(orderId);
        if (Objects.nonNull(orderChangeRecord)) {
            orderWorkDRO.setFirstVisitScanTime(orderChangeRecord.getFirstVisitScanTime());
            orderWorkDRO.setFirstMasterImageTime(orderChangeRecord.getFirstMasterImageTime());
        }

        OrderExtend orderExtend = orderExtendService.findMiniOrderExtendByOrderId(orderId);
        if (Objects.nonNull(orderExtend)) {
            orderWorkDRO.setCallId(orderExtend.getCallId());
            orderWorkDRO.setOrderClueId(orderExtend.getClueId());
        }

        // 多工程师
        List<OrderMaster> orderMasterList = orderMasterService.listMasterByWorkId(orderWorkDRO.getOrderId(), orderWorkDRO.getWorkId());
        if (CollectionUtils.isNotEmpty(orderMasterList)) {
            orderWorkDRO.setOrderMasterList(BeanMapper.mapList(orderMasterList, OrderMasterDRO.class));
        }
        // 责任工程师
        if (Objects.nonNull(orderChangeRecord) && NumberUtil.isNotNullOrZero(orderChangeRecord.getCancelLiableMasterId())) {
            orderWorkDRO.setCancelLiableMasterId(orderChangeRecord.getCancelLiableMasterId());
            orderWorkDRO.setCancelLiableMasterName(orderChangeRecord.getCancelLiableMasterName());
        }

        // 内部价
        List<OrderServiceItem> orderServiceItemList = orderServiceItemService.listByOrderId(orderWork.getOrderId());
        if (CollectionUtils.isNotEmpty(orderMasterList)) {
            int internalSettlementPrice = orderServiceItemList.stream()
                    .filter(e -> e.getInternalTotalPrice() != null)
                    .mapToInt(OrderServiceItem::getInternalTotalPrice).sum();
            orderWorkDRO.setInternalStatementAmount(internalSettlementPrice);
        }

        return ResponseDTO.success(orderWorkDRO);
    }

    @Override
    public ResponseDTO<OrderWorkInfoDRO> getOrderWorkInfoToTrackWorkByKey(@NotNull Long workId, @NotNull Long orderId) {
        // 查询订单
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
        if (Objects.isNull(orderWork)) {
            return ResponseDTO.fail("订单不存在");
        }
        // 查询订单详情
        OrderDetail orderDetail = orderDetailService.findOrderDetailByKey(orderId);
        // 查询改约改派次数
        OrderChangeRecord orderChangeRecord = orderChangeRecordService.getChangeRecordByOrderId(orderId);

        String cityName = orderDetail.getCityName();

        OrderWorkInfoDRO orderWorkInfoDRO = new OrderWorkInfoDRO();
        orderWorkInfoDRO.setOrderId(orderWork.getOrderId());
        orderWorkInfoDRO.setWorkId(orderWork.getWorkId());
        orderWorkInfoDRO.setPlat(orderWork.getPlat());
        orderWorkInfoDRO.setPlatWork(orderWork.getPlatWork());
        orderWorkInfoDRO.setCityName(cityName);
        orderWorkInfoDRO.setChannelId(orderWork.getChannelId());
        orderWorkInfoDRO.setChannelName(orderWork.getChannelName());
        orderWorkInfoDRO.setCompanyName(orderWork.getCompanyName());
        orderWorkInfoDRO.setDutyTime(orderWork.getDutyTime());
        orderWorkInfoDRO.setCreateTime(orderWork.getCreateTime());
        orderWorkInfoDRO.setContact(orderDetail.getContactName());
        orderWorkInfoDRO.setTelephone(orderDetail.getTelephone());
        orderWorkInfoDRO.setTelephone2(orderDetail.getTelephone2());
        orderWorkInfoDRO.setTelephone3(orderDetail.getTelephone3());
        orderWorkInfoDRO.setPayStatusName(PayConsts.getPayStatusName(orderWork.getPayStatus()));
        orderWorkInfoDRO.setReplyVisiterId(orderWork.getReplyVisiterId());
        orderWorkInfoDRO.setReplyVisitTime(orderWork.getReplyVisitTime());
        orderWorkInfoDRO.setBizType(orderWork.getBizType());
        orderWorkInfoDRO.setServiceCompleteReviewStatusName(OrderConsts.getReviewStatusName(orderWork.getServiceCompleteReviewStatus()));
        orderWorkInfoDRO.setStatusName(OrderStatusConsts.getWorkStatusName(orderWork.getStatus()));
        orderWorkInfoDRO.setResultStatusName(OrderStatusConsts.getWorkResultStatusName(orderWork.getResultStatus()));

        //完整地址
        orderWorkInfoDRO.setFullAddress(orderDetail.getProvinceName() + " " + cityName + " "
                + orderDetail.getCountyName() + " " + orderDetail.getStreet() + " "
                + StringUtils.defaultString(orderDetail.getAddress(), ""));

        // 没有预约时间订单变化表为空
        if (Objects.isNull(orderChangeRecord)) {
            orderWorkInfoDRO.setDutyTimeModifyCount(0);
            orderWorkInfoDRO.setDistributeCount(0);
        } else {
            orderWorkInfoDRO.setDutyTimeModifyCount(orderChangeRecord.getDutyTimeModifyCount());
            orderWorkInfoDRO.setDistributeCount(orderChangeRecord.getDistributeCount());
        }

        List<OrderLog> logList = orderLogBService.findOrderLogsByWorkId(workId);
        List<OrderLogDRO> orderLogDROList = BeanMapper.mapList(logList, OrderLogDRO.class);
        orderWorkInfoDRO.setOrderLogList(orderLogDROList);

        //有师傅才查询师傅信息
        if (orderWork.getMasterId() != 0) {
            List<Integer> masterIds = Lists.newArrayListWithCapacity(1);
            masterIds.add(orderWork.getMasterId());
            List<OrderMaster> orderMasterList = orderMasterService.listMasterByMasterIdList(orderId, workId, masterIds);
            orderWorkInfoDRO.setEngineerPhone(orderMasterList.get(0).getMasterPhone());
            orderWorkInfoDRO.setEngineerName(orderWork.getMasterName());
            // 查询工程师产品分组
            try {
                if (log.isDebugEnabled()) {
                    log.debug("getOrderWorkInfoToTrackWorkByKey#getProductGroupByEngineerIdAndBizType 入参 [{}] [{}]",orderWork.getMasterId(),orderWork.getBizType());
                }
                ResponseDTO<Option<Integer>> responseDTO = engineerCooperateInfoListRemoteService.getProductGroupByEngineerIdAndBizType(
                        orderWork.getMasterId(), orderWork.getBizType());
                if (log.isDebugEnabled()) {
                    log.info("getOrderWorkInfoToTrackWorkByKey#getProductGroupByEngineerIdAndBizType 出参 [{}]",JSON.toJSONString(responseDTO)); 
                }
                if (responseDTO.isSuccess() && Objects.nonNull(responseDTO.getData())) {
                    orderWorkInfoDRO.setEngineerName(StringUtils.defaultString(responseDTO.getData().getLabel()) + "-"
                            + orderWork.getMasterName());
                }
            } catch (Exception e) {
                log.error("getOrderWorkInfoToTrackWorkByKey#getProductGroupByEngineerIdAndBizType 异常 [{}]", e);
            }
        }

        // 有投诉才查询
        Integer complaintStatus = orderWork.getComplaintStatus();
        if (Objects.equals(complaintStatus, GlobalConsts.YES)) {
            ResponseDTO<List<ChsComplainSimpleDRO>> complainResponse = chsComplainApiListRemoteService
                    .listComplainSimpleByOrderId(orderId);
            if (complainResponse.isSuccess() && CollectionUtil.isNotNullOrEmpty(complainResponse.getData())) {
                List<ChsComplainSimpleDRO> items = complainResponse.getData();
                List<ComplaintDRO> complaintVOS = BeanMapper
                        .mapList(items, ComplaintDRO.class);
                orderWorkInfoDRO.setComplaintVOList(complaintVOS);
            }
        }

        // 有异常才查询
        Integer abnormalStatus = orderWork.getAbnormalStatus();
        if (Objects.equals(abnormalStatus, GlobalConsts.YES)) {
            try {
                ResponseDTO<List<AbnormalCategDRO>> listResponseDTO = abnormalListRemoteService.listAbnormalCategByOrderId(orderId);
                if (listResponseDTO.isSuccess() && !org.apache.commons.collections4.CollectionUtils.isEmpty(listResponseDTO.getData())) {
                    List<AbnormalCategDRO> data = listResponseDTO.getData();
                    List<AbnormalDRO> abnormalVOList = BeanMapper
                            .mapList(data, AbnormalDRO.class);
                    orderWorkInfoDRO.setAbnormalVOList(abnormalVOList);
                }
            } catch (Exception e) {
            }
        }

        // 查询订单产品数据 && 产品的服务项
        List<OrderProduct> orderProductList = orderProductService.listOrderProductByOrderId(orderId);
        List<DetailProductDRO> productVOList = BeanMapper
                .mapList(orderProductList, DetailProductDRO.class);
        productVOList.forEach(item -> {
            List<String> fault = Lists.newArrayList();
            if (StringUtils.isNotBlank(item.getFault())) {
                List<MapDTO> faultList = JSON.parseArray(item.getFault(), MapDTO.class);
                fault.addAll(Optional.ofNullable(faultList).orElse(Lists.newArrayListWithCapacity(0)).stream()
                        .map(MapDTO::getMapName).collect(Collectors.toList()));
            }
            if (StringUtils.isNotBlank(item.getRemark())) {
                fault.add(item.getRemark());
            }
            item.setFaultInfo(StringUtils.join(fault, "；"));
        });
        orderWorkInfoDRO.setProductList(productVOList);

        // 是否退款单
        boolean isRefundOrder = Objects.equals(OrderConsts.ORDER_TYPE_REFUND, orderWork.getType());
        if (!isRefundOrder) {

            List<OrderProductExtend> orderProductExtendList = orderProductExtendService.listByOrderId(orderId);
            Map<Long, OrderProductExtend> orderProductMap = orderProductExtendList.stream()
                    .collect(Collectors.toConcurrentMap(OrderProductExtend::getProExtId, orderProduct -> orderProduct));
            List<OrderServiceItem> orderServiceItemList = orderServiceItemService.listByOrderId(orderId);
            if (!orderServiceItemList.isEmpty()) {
                Map<Long, List<OrderServiceItem>> serviceItemMap = orderServiceItemList.stream()
                        .collect(Collectors.groupingBy(OrderServiceItem::getProExtId));

                List<DetailProductDRO> serviceItemVoList = Lists.newArrayList();
                serviceItemMap.forEach((key, value) -> {
                    OrderProductExtend orderProduct = orderProductMap.get(key);
                    DetailProductDRO detailProductDRO = new DetailProductDRO();
                    detailProductDRO.setProExtId(orderProduct.getProExtId());
                    detailProductDRO.setProductName(orderProduct.getProductName());
                    Integer totalAmount = 0;
                    List<DetailServiceItemDRO> serviceItemVOList = Lists.newArrayList();

                    for (OrderServiceItem serviceItem : value) {
                        DetailServiceItemDRO serviceItemVO = new DetailServiceItemDRO();
                        serviceItemVO.setServiceItemName(serviceItem.getServItemName());
                        serviceItemVO.setAmount(serviceItem.getTotalPrice());
                        serviceItemVO.setNumber(serviceItem.getNumber());

                        // 复制故障项相关的数据
                        if (servItemBService.isQuotationType(orderWork.getServItemType())) {
                            if (!Objects.isNull(serviceItem.getItemDetail())) {
                                BeanMapper.copy(serviceItem.getItemDetail(), serviceItemVO);
                            }
                        }

                        Integer totalPrice = serviceItem.getTotalPrice();
                        serviceItemVOList.add(serviceItemVO);
                        totalAmount += totalPrice;
                    }
                    detailProductDRO.setServiceItemVOList(serviceItemVOList);
                    detailProductDRO.setServiceItemTotalAmount(totalAmount);
                    serviceItemVoList.add(detailProductDRO);
                });
                serviceItemVoList.sort(Comparator.comparing(DetailProductDRO::getProExtId));
                orderWorkInfoDRO.setServiceItemList(serviceItemVoList);
            }
        }
        return ResponseDTO.success(orderWorkInfoDRO);
    }

    @Override
    public ResponseDTO<OrderWorkDRO> getSimpleOrderWorkInfoByKey(@NotNull Long workId, @NotNull Long orderId) {
        String dynamicOrderWorkSql = "work_id, order_id, status, serv_categ_id, show_serv_categ_name, " +
                "serv_product_group_id, channel_id, channel_name, delivery, wait_part";
        String dynamicOrderDetailSql = "detail_id, serv_categ_name";
        OrderWork simpleOrderWork = orderWorkService.findDynamicOrderWorkByKey(dynamicOrderWorkSql, orderId, workId);
        OrderDetail orderDetail = orderDetailService.findDynamicOrderDetailByKey(dynamicOrderDetailSql, orderId);
        if (Objects.isNull(simpleOrderWork) || Objects.isNull(orderDetail)) {
            return ResponseDTO.fail("工单不存在");
        }

        OrderWorkDRO workDRO = new OrderWorkDRO();
        workDRO.setWorkId(simpleOrderWork.getWorkId());
        workDRO.setOrderId(simpleOrderWork.getOrderId());
        workDRO.setStatus(simpleOrderWork.getStatus());
        workDRO.setServCategId(simpleOrderWork.getServCategId());
        workDRO.setServCategName(orderDetail.getServCategName());
        workDRO.setServProductGroupId(simpleOrderWork.getServProductGroupId());
        workDRO.setChannelId(simpleOrderWork.getChannelId());
        workDRO.setChannelName(simpleOrderWork.getChannelName());
        workDRO.setDelivery(simpleOrderWork.getDelivery());
        workDRO.setWaitPart(simpleOrderWork.getWaitPart());

        return ResponseDTO.success(workDRO);
    }

    @Override
    public ResponseDTO<List<OrderWorkDRO>> listOrderWorkByOrderIdAndType(Long orderId, Integer type) {
        OrderWorkQuery query = new OrderWorkQuery();
        query.setOrderIdList(Arrays.asList(orderId));
        query.setWorkType(Arrays.asList(type));
        query.setPageSize(1000);
        List<EsOrderWork> esOrderWorkList = orderWorkListBService.listPageOrderWorkByQuery(query);
        if (esOrderWorkList.isEmpty()) {
            return ResponseDTO.fail("订单不存在");
        }
        List<OrderWorkDRO> list = Lists.newArrayListWithCapacity(esOrderWorkList.size());
        esOrderWorkList.forEach(e -> {
            OrderWorkDRO dro = BeanMapper.map(e, OrderWorkDRO.class);
            EsOrderWorkProduct product = e.getProductList().get(0);
            dro.setProductName(product.getProductName());
            dro.setProductNum(product.getNumber());
            dro.setWorkId(e.getId());
            list.add(dro);
        });
        return ResponseDTO.success(list);
    }


    @Override
    public ResponseDTO<SourceChannelOrderPageDRO> listPageSourceChannelOrderByQuery(SourceChannelOrderQueryDIO query) {

        if (log.isDebugEnabled()) {
            log.debug("#oms#listPageSourceChannelOrderByQuery 初始入参：{}", JSON.toJSONString(query));
        }

        SourceChannelOrderPageDRO pageDRO = new SourceChannelOrderPageDRO();
        pageDRO.setTotalCount(0);
        pageDRO.setOrderList(Lists.newArrayList());
        OrderWorkSourceChannelQuery channelQuery = BeanMapper.map(query, OrderWorkSourceChannelQuery.class);
        channelQuery.setPlat(null);
        channelQuery.setWorkType(Arrays.asList(OrderConsts.ORDER_TYPE_NEW, OrderConsts.ORDER_TYPE_REWORK));

        String orderField = channelQuery.getOrderField();
        // 默认排序 下单时间倒序排
        if (StringUtils.isBlank(orderField)) {
            channelQuery.setDefaultOrder(GlobalConsts.YES);
            channelQuery.setOrderField("receiveTime");
        }

        if (log.isDebugEnabled()) {
            log.debug("#oms#listPageSourceChannelOrderByQuery 入参：{}", JSON.toJSONString(channelQuery));
        }
        List<EsOrderWork> esOrderWorkList = orderWorkListBService.listPageOrderWorkByQuery(channelQuery);
        if (log.isDebugEnabled()) {
            log.debug("#oms#listPageSourceChannelOrderByQuery 出参：{}", JSON.toJSONString(esOrderWorkList));
        }

        // 结果为空直接返回
        if (CollectionUtil.isNullOrEmpty(esOrderWorkList)) {
            return ResponseDTO.success(pageDRO);
        }
        // 解密电话
        orderEncryptService.batchDecryptEsOrderWork(esOrderWorkList, EncryptFieldTypeEnum.USER_TELPHONE);

        // count
        Integer totalCount = channelQuery.getTotalCount();
        pageDRO.setTotalCount(totalCount);

        // list
        List<SourceChannelOrderDRO> orderList = Lists.newArrayListWithCapacity(esOrderWorkList.size());
        esOrderWorkList.forEach(e -> {
            SourceChannelOrderDRO orderDRO = BeanMapper.map(e, SourceChannelOrderDRO.class);
            String mobile = StringUtil.formatHideMobile(e.getContact().getPhone()[0]);
            orderDRO.setMobile(mobile);
            orderList.add(orderDRO);
        });
        pageDRO.setOrderList(orderList);
        return ResponseDTO.success(pageDRO);
    }

    @Override
    public ResponseDTO<Map<Long, OrderWorkDRO>> listOrderWorkByWorkIdList(@NotEmpty List<Long> orderIdList) {
        if (orderIdList.size() > 1000) {
            return ResponseDTO.fail("入参大小超过1000");
        }

        OrderWorkQuery query = new OrderWorkQuery();
        query.setOrderIdList(orderIdList);
        query.setPageSize(1000);
        List<EsOrderWork> esOrderWorkList = orderWorkListBService.listPageOrderWorkByQuery(query);
        if (CollectionUtil.isNullOrEmpty(esOrderWorkList)) {
            return ResponseDTO.success(Collections.emptyMap());
        }
        // 解密地址
        orderEncryptService.batchDecryptEsOrderWork(esOrderWorkList, EncryptFieldTypeEnum.USER_ADDRESS);
        Map<Long, OrderWorkDRO> map = Maps.newHashMapWithExpectedSize(orderIdList.size());
        esOrderWorkList.forEach(e -> {
            OrderWorkDRO dro = BeanMapper.map(e, OrderWorkDRO.class);
            if (Objects.nonNull(e.getContact())) {
                BeanMapper.copy(e.getContact(), dro);
                if (e.getContact().getLocationShape() != null) {
                    Double[] coordinates = e.getContact().getLocationShape().getCoordinates();
                    dro.setLongitude(coordinates[0]);
                    dro.setLatitude(coordinates[1]);
                }
            }
            dro.setWorkId(e.getId());
            EsOrderWorkProduct product = e.getProductList().get(0);
            dro.setProductName(product.getProductName());
            dro.setProductNum(product.getNumber());
            dro.setDelivery(e.getHasDelivery() ? GlobalConsts.YES : GlobalConsts.NO);
            dro.setWaitPart(e.getHasWaitPart() ? GlobalConsts.YES : GlobalConsts.NO);
            map.put(dro.getOrderId(), dro);
        });

        return ResponseDTO.success(map);
    }

    @Override
    public ResponseDTO<List<Integer>> listChannelIdTwentyFourByMobile(@NotNull String mobile) {

        OrderWorkQuery query = new OrderWorkQuery();
        query.setConcatPhone(mobile);
        query.setPageSize(100);
        Date end = DateUtil.getNow();

        // 24小时之内
//        Date start = DateUtil.addDays(end, -1);
        // TODO lujia 测试改为20分钟
        Date start = DateUtil.addMinute(end, -20);
        String endStr = DateUtil.dateFormatToString(end, DateUtil.FORMAT_DEFAULT);
        String startStr = DateUtil.dateFormatToString(start, DateUtil.FORMAT_DEFAULT);
        query.setReceiveTime(startStr + "," + endStr);
        query.setIncludes(Arrays.asList("channelId"));
        query.setWorkType(Arrays.asList(OrderConsts.ORDER_TYPE_NEW, OrderConsts.ORDER_TYPE_REWORK));

        List<EsOrderWork> orderWorkList = orderWorkListBService.listPageOrderWorkByQuery(query);
        if (CollectionUtil.isNullOrEmpty(orderWorkList)) {
            return ResponseDTO.fail("无工单");
        }

        List<Integer> channelIdList = orderWorkList.stream().map(EsOrderWork::getChannelId).distinct().collect(Collectors.toList());
        return ResponseDTO.success(channelIdList);
    }


    @Override
    public ResponseDTO<OrderWorkDetailSpoolDRO> getRecentOneOrderIdByUserId(Long userId) {
        log.info("根据userId{}查询该用户最近一次派单时间的订单", userId);
        OrderWorkQuery query = new OrderWorkQuery();
        query.setWorkType(Arrays.asList(OrderConsts.ORDER_TYPE_NEW, OrderConsts.ORDER_TYPE_REWORK));
        query.setUserId(userId);
        query.setPageSize(1000);
        query.setPageIndex(1);
        query.setOrderField("distributeTime");
        query.setIncludes(Arrays.asList("id", "orderId", "distributeTime"));
        query.setWorkType(Lists.newArrayList(OrderConsts.ORDER_TYPE_REWORK, OrderConsts.ORDER_TYPE_NEW));
        List<EsOrderWork> esOrderWorkList = orderWorkListBService.listPageOrderWorkByQuery(query);

        if (CollectionUtils.isEmpty(esOrderWorkList)) {
            return ResponseDTO.success();
        }

        EsOrderWork esOrderWork = esOrderWorkList.get(0);
        if (esOrderWork.getDistributeTime() == null) {
            return ResponseDTO.success();
        }

        OrderWorkDetailSpoolDRO dro = new OrderWorkDetailSpoolDRO();
        dro.setWorkId(esOrderWork.getId());
        dro.setOrderId(esOrderWork.getOrderId());

        return ResponseDTO.success(dro);
    }

    @Override
    public ResponseDTO<List<OrderWorkDetailSpoolDRO>> listOrderDetailSpoolById(@NotNull Long workId, @NotNull Long orderId) {

        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
        if (Objects.isNull(orderWork)) {
            return ResponseDTO.fail("订单不存在");
        }

        List<OrderWorkDetailSpoolDRO> detailOrderList = Lists.newArrayList();
        List<OrderLog> orderLogsByTypes = orderLogBService.findOrderLogsByTypes(orderId, OrderDeatilSpoolConsts.types);
        if (CollectionUtils.isEmpty(orderLogsByTypes)) {
            return ResponseDTO.success(detailOrderList);
        }

        List<OrderWorkDetailSpoolDRO> contactList = new ArrayList<>();
        orderLogsByTypes.forEach(item -> {
            OrderWorkDetailSpoolDRO detail = new OrderWorkDetailSpoolDRO();
            detail.setOrderId(orderWork.getOrderId());
            detail.setWorkId(orderWork.getWorkId());
            detail.setOperateTime(item.getCreateTime());
            detail.setLogType(item.getType());
            detail.setLogTypeName(OrderDeatilSpoolConsts.getOperateTypeName(item.getType()));

            if (Objects.equals(OrderLogConsts.ORDER_LOG_TYPE_COMPLETE, item.getType())) {
                Integer originalAmount = Optional.ofNullable(orderWork.getOriginalAmount()).orElse(0); // 总价
                Integer discountAmount = Optional.ofNullable(orderWork.getDiscountAmount()).orElse(0); // 优惠
                Integer totalAmount = Optional.ofNullable(orderWork.getTotalAmount()).orElse(0); // 实付款
                String remark = String.format("总价¥%.2f，优惠¥%.2f，实付款¥%.2f",
                        AmountUtil.fen2Yuan(originalAmount).doubleValue(),
                        AmountUtil.fen2Yuan(discountAmount).doubleValue(),
                        AmountUtil.fen2Yuan(totalAmount).doubleValue());
                detail.setLogRemark(OrderDeatilSpoolConsts.getOperateTypeRemark(item.getType(), null, null, remark));
            } else if (Objects.equals(OrderLogConsts.ORDER_LOG_TYPE_DISTRIBUTE, item.getType())) {
                String logMasterName = "";
                String content = item.getContent();
                int index = content.indexOf("->");
                if (StringUtils.isNotBlank(content)) {
                    if (index != -1) {
                        String[] text = content.split("->");
                        if (text.length > 1) {
                            logMasterName = text[1];
                            if (StringUtils.isNotBlank(logMasterName.trim())) {
                                String[] name = logMasterName.split("\n");
                                logMasterName = name[0];
                            }
                        }
                    }
                }
                detail.setLogRemark(OrderDeatilSpoolConsts.getOperateTypeRemark(item.getType(), logMasterName, null, null));
                detail.setMasterName(logMasterName);
            } else {
                detail.setLogRemark(OrderDeatilSpoolConsts.getOperateTypeRemark(item.getType(), null, null, null));
            }

            // 处理工程师联系用户
            if (Objects.equals(OrderLogConsts.ORDER_LOG_TYPE_CONTACT_USER, item.getType())) {
                contactList.add(detail);
            } else {
                if (CollectionUtil.isNotNullOrEmpty(contactList)) {
                    OrderWorkDetailSpoolDRO contactOneDetail = contactList.get(0);
                    detailOrderList.add(contactOneDetail);
                    contactList.clear();
                }
                detailOrderList.add(detail);
            }
        });

        String masterName = "";
        String masterPhone = "";
        if (NumberUtil.isNotNullOrZero(orderWork.getMasterId())) {
            if (log.isDebugEnabled()) {
                log.debug("listOrderDetailSpoolById#getEngineerDetailById 入参 [{}]",orderWork.getMasterId());
            }
            ResponseDTO<ForeignEngineerDetailInfoDRO> resp = engineerListRemoteService.getEngineerDetailById(orderWork.getMasterId());
            if (log.isDebugEnabled()) {
                log.info("listOrderDetailSpoolById#getEngineerDetailById 出参 [{}]", JSON.toJSONString(resp));
            }
            if (resp.isSuccess() && Objects.nonNull(resp.getData())) {
                masterName = resp.getData().getRealName();
                masterPhone = resp.getData().getMobile();
            }
        }

        Map<Integer, List<OrderWorkDetailSpoolDRO>> orderLog = detailOrderList.stream().collect(Collectors.groupingBy(OrderWorkDetailSpoolDRO::getLogType));
        String finalMasterName = masterName;
        String finalMasterPhone = masterPhone;

        orderLog.forEach((type, workDetailSpoolDRO) -> {
            //领单
            if (Objects.equals(OrderLogConsts.ORDER_LOG_TYPE_TAKE, type)) {
                OrderWorkDetailSpoolDRO detail = workDetailSpoolDRO.get(0);
                if (orderWork.getStatus() > OrderStatusConsts.WORK_STATUS_DISTRIBUTE) {
                    detail.setMasterName(finalMasterName);
                    detail.setMasterPhone(finalMasterPhone);
                    detail.setLogRemark(OrderDeatilSpoolConsts.getOperateTypeRemark(type, finalMasterName, finalMasterPhone, null));
                } else {
                    detail.setLogRemark(OrderDeatilSpoolConsts.getOperateTypeRemark(type, null, null, null));
                }

            }
            //联系用户
            else if (Objects.equals(OrderLogConsts.ORDER_LOG_TYPE_CONTACT_USER, type)) {
                OrderWorkDetailSpoolDRO detail = workDetailSpoolDRO.get(0);
                if (orderWork.getStatus() > OrderStatusConsts.WORK_STATUS_TAKE) {
                    detail.setMasterName(finalMasterName);
                    detail.setLogRemark(OrderDeatilSpoolConsts.getOperateTypeRemark(type, finalMasterName, null, null));
                } else {
                    detail.setLogRemark(OrderDeatilSpoolConsts.getOperateTypeRemark(type, null, null, null));
                }
            }
        });

        return ResponseDTO.success(detailOrderList);
    }

    /**
     * 获取工程师已完成工单
     *
     * @param startTime 开始时间（完成时间）
     * @param endTime   结束时间（完成时间）
     * @param masterId  工程师id
     * @return 最大返回1000条
     */
    @Override
    public ResponseDTO<List<CompletedOrder>> listCompletedOrderByMasterId(Date startTime, Date endTime, Integer masterId) {
        if (log.isDebugEnabled()) {
            log.debug("ZsNormalOrderListRemoteService#listCompletedOrderByMasterId 入参startTime:{},endTime:{},masterId:{}", startTime, endTime, masterId);
        }
        OrderWorkQuery query = new OrderWorkQuery();
        query.setWorkType(Arrays.asList(OrderConsts.ORDER_TYPE_NEW, OrderConsts.ORDER_TYPE_REWORK));
        query.setMasterId(masterId);
        query.setCompleteTime(String.format("%s,%s",
                DateUtil.dateFormatToString(startTime, DateUtil.FORMAT_DATE + " 00:00:00"),
                DateUtil.dateFormatToString(endTime, DateUtil.FORMAT_DATE + " 23:59:59")));
        query.setIncludes(Arrays.asList("id", "workId", "plat", "platWork", "companyId", "manageCompanyId", "bizType"));
        query.setPageSize(1000);
        List<EsOrderWork> esOrderWorks = orderWorkListBService.listPageOrderWorkByQuery(query);
        List<CompletedOrder> list = Lists.newArrayListWithCapacity(esOrderWorks.size());
        esOrderWorks.forEach(e -> {
            CompletedOrder order = BeanMapper.map(e, CompletedOrder.class);
            order.setWorkId(e.getId());
            list.add(order);
        });
        if (log.isDebugEnabled()) {
            log.info("ZsNormalOrderListRemoteService#listCompletedOrderByMasterId 返回{}", list);
        }
        return ResponseDTO.success(list);
    }

    @Override
    public ResponseDTO<List<CheckoutedOrder>> listCheckoutedOrderByMasterId(Date startTime, Date endTime, Integer masterId) {
        log.info("ZsNormalOrderListRemoteService#listCheckoutedOrderByMasterId 入参startTime:{},endTime:{},masterId:{}", startTime, endTime, masterId);
        OrderWorkQuery query = new OrderWorkQuery();
        query.setWorkType(Arrays.asList(OrderConsts.ORDER_TYPE_NEW, OrderConsts.ORDER_TYPE_REWORK));
        query.setMasterId(masterId);
        query.setWorkResultStatus(OrderStatusConsts.WORK_RESULT_SUCCESS);
        query.setCheckoutTime(String.format("%s,%s",
                DateUtil.dateFormatToString(startTime, DateUtil.FORMAT_DEFAULT),
                DateUtil.dateFormatToString(endTime, DateUtil.FORMAT_DEFAULT)));
        query.setIncludes(Arrays.asList("id", "orderId", "masterId", "plat", "platWork", "bizType", "type", "resultStatus", "servItemType", "servProductGroupId", "servProductGroupName",
                "checkoutTime",
                "companyId", "manageCompanyId", "gridCompanyId", "gridManageCompanyId",
                "provinceId", "provinceName", "cityId", "cityName", "countyId", "countyName"));
        query.setPageSize(1000);

        List<EsOrderWork> esOrderWorks = orderWorkListBService.listPageOrderWorkByQuery(query);
        List<CheckoutedOrder> list = Lists.newArrayListWithCapacity(esOrderWorks.size());

        esOrderWorks.forEach(e -> {
            CheckoutedOrder order = BeanMapper.map(e, CheckoutedOrder.class);
            order.setWorkId(e.getId());
            list.add(order);
        });

        log.info("ZsNormalOrderListRemoteService#listCheckoutedOrderByMasterId 返回{}", list);
        return ResponseDTO.success(list);
    }

    /**
     *
     * 按完成时间获取订单
     * @return 最大返回1000条
     * @author heciqi
     */
    @ApiOperation(value = "按完成时间获取订单", response = ResponseDTO.class)
    @Override
    public ResponseDTO<List<MasterOrderWorkDRO>> listPageByCompleteTime(PageByCompleteTimeDIO pageDIO) {
        if (log.isDebugEnabled()) {
            log.debug(JSON.toJSONString(pageDIO));
        }

        OrderWorkQuery query = new OrderWorkQuery();
        query.setWorkType(Arrays.asList(OrderConsts.ORDER_TYPE_NEW, OrderConsts.ORDER_TYPE_REWORK));
        query.setCompleteTime(String.format("%s,%s",
                DateUtil.dateFormatToString(pageDIO.getStartCompleteTime(), DateUtil.FORMAT_DEFAULT),
                DateUtil.dateFormatToString(pageDIO.getEndCompleteTime(), DateUtil.FORMAT_DEFAULT)));
        query.setIncludes(Arrays.asList("id", "orderId", "type","bizType", "servProductGroupId",
                "servProductGroupName", "masterId", "masterName", "completeTime"));
        query.setPageIndex(pageDIO.getPageIndex());
        query.setPageSize(1000);

        List<EsOrderWork> esOrderWorks = orderWorkListBService.listPageOrderWorkByQuery(query);
        List<MasterOrderWorkDRO> list = Lists.newArrayListWithCapacity(esOrderWorks.size());
        esOrderWorks.forEach(e -> {
            MasterOrderWorkDRO order = BeanMapper.map(e, MasterOrderWorkDRO.class);
            order.setWorkId(e.getId());
            list.add(order);
        });
        pageDIO.setTotalCount(query.getTotalCount());
        if (log.isDebugEnabled()) {
            log.debug("listPageByCompleteTime出参=>count:{}list:{}", query.getTotalCount(), JSON.toJSONString(list));
        }
        return ResponseDTO.success(list);
    }

    /**
     *
     * 按收单时间获取订单1
     * @return 最大返回1000条
     * @author heciqi
     */
    @ApiOperation(value = "按收单时间获取订单", response = ResponseDTO.class)
    @Override
    public ResponseDTO<List<MasterOrderWorkDRO>> listPageByCheckoutTime(PageByCheckoutTimeDIO pageDIO) {
        if (log.isDebugEnabled()) {
            log.debug(JSON.toJSONString(pageDIO));
        }

        OrderWorkQuery query = new OrderWorkQuery();
        query.setWorkType(Arrays.asList(OrderConsts.ORDER_TYPE_NEW, OrderConsts.ORDER_TYPE_REWORK));
        query.setCheckoutTime(String.format("%s,%s",
                DateUtil.dateFormatToString(pageDIO.getStartTime(), DateUtil.FORMAT_DEFAULT),
                DateUtil.dateFormatToString(pageDIO.getEndTime(), DateUtil.FORMAT_DEFAULT)));
        query.setIncludes(Arrays.asList("id", "orderId", "type","bizType", "servProductGroupId",
                "servProductGroupName", "masterId", "masterName", "completeTime"));
        query.setWorkResultStatus(OrderStatusConsts.WORK_RESULT_SUCCESS);
        query.setPageIndex(pageDIO.getPageIndex());
        query.setPageSize(1000);

        List<EsOrderWork> esOrderWorks = orderWorkListBService.listPageOrderWorkByQuery(query);
        List<MasterOrderWorkDRO> list = Lists.newArrayListWithCapacity(esOrderWorks.size());
        esOrderWorks.forEach(e -> {
            MasterOrderWorkDRO order = BeanMapper.map(e, MasterOrderWorkDRO.class);
            order.setWorkId(e.getId());
            list.add(order);
        });
        pageDIO.setTotalCount(query.getTotalCount());
        if (log.isDebugEnabled()) {
            log.debug("listPageByCheckoutTime=>count:{}list:{}", query.getTotalCount(), JSON.toJSONString(list));
        }
        return ResponseDTO.success(list);
    }
}
